<!--
    脚手架创建Vue项目：
    1. vue ui 可视化创建项目
    2. vue create 项目目录
    
    Router:路由
    Unit Tests:单元测试
    Linter / Formatter:Eslint代码规范检测
    选择Runtime-only（性能更好，所使用的代码量更少）

    启动项目：npm run serve
    编译项目：npm run build

    关闭Eslint代码规范检测（神TM的各种奇葩规范）：\config\index.js\useEslint: false

    解决build后打开空白问题：
        新建vue.config.js，内容：
            module.exports = {
                publicPath: './'
            }
-->


<!--
    概念：

    后端渲染：由后端处理将渲染好的HTML页面并发送给客户端
    后端路由：由后端处理URL和页面之间的映射关系

    前后端分离：
        后端只负责提供数据
    前端渲染:
        浏览器中显示的网页中的大部分内容,都是由前端写的js代码在浏览器中执行,最终渲染出来的网页.

    单页面富应用（SPA）：
        整个页面只有一个HTML，所有页面都在里面（依次隐藏显示）
    前端路由：
        URL与HTML页面间的映射关系

    路由：
        1.创建路由组件
            views\XXX.vue

            <template>
                <div class="XXX"">
                    
                </div>
            </template>

        2.配置路由映射
            router\index.js

            import XXX from '../views/XXX.vue'
            const routes = [
            {
                path: '/XXX',
                name: 'XXX',
                component: XXX
            }

        3.使用路由：
            <router-link>to="/XXX">XXX</router-link>
            <router-link>to="/XXX" tag="指定渲染的组件（如button、li）">XXX</router-link>
            <router-view />

            代码跳转：
                this.$router.push('/XXX')

    动态路由：
        index.js:
        path: '/User/:变量名'



    路由懒加载：
        const routes = [
        {
            path: '/XXX',
            name: 'XXX',
            component: () => import('../views/XXX.vue')
        }

        路由传参：
            方法1：

            XXX.vue:
            <router-link :to="'/XXX/'+变量名">用户</router-link>
                        
            代码传参：
            this.$router.push('/XXX' + this.变量名)
        
            访问参数：this.$route.params.XXX


            方法2：

            <router-link :to="{path: '/跳转页面',query: {参数1: 值1[,参数2: 值2]}}">页面名</router-link>

            代码传参：
                <button @click="传参()">用户</button>

                传参() {
                    this.$router.push({
                    path: '/跳转页面',
                    query: {
                    参数1: 值1,
                    参数2: 值2,
                    }
                })
            }

            访问参数：{{$route.query.参数名}}
-->

<!--
    导航守卫：
    index.js

    const routes = [
    {
        path: '/XXX',
        meta: {
            title: "页面名"
    }

    router.beforeEach((to, from, next) => { 
        //从form跳转到to
        document.title=to.matched[0].meta.title
        next()
    })
-->

<!--
    不重新渲染：
        <keep-alive>
            <router-view/>
        </keep-alive>
    
        指定部分页面重新渲染（支持正则表达式）
    <keep-alive exclude="页面名称1[,页面名称2]">

-->


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        [v-cloak] {
            display: none;
        }

        .active {
            color: red;
        }
    </style>
</head>

<body>
    <!--v-cloak表示在Vue解析之前不显示-->
    <div id="app" v-cloak>

        <h1>{{message}}</h1>
        <!--v-model表示双向绑定，后接变量名-->
        <br>双向绑定：
        <input type="text" v-model="message">
        <br>懒加载：（失去焦点、回车则更新数据）
        <input type="text" v-model.lazy="message">


        <br>number修饰符（转换为nmuber类型）
        <input type="number" v-model.number="message">
        <br>trim修饰符（删除字符串首尾的空格）
        <input type="text" v-model.trim="message">

        <!--单选框-->
        <br>
        <input type="radio" id="male" name="sev" value="男" v-model="sex">男
        <input type="radio" id="female" name="sev" value="女" v-model="sex">女
        <br>
        <h2>{{sex}}</h2>

        <!--多选框-->
        <!--label标签作用：点击文字也能触发检查框-->
        <label><input type="checkbox" id="agree" v-model="isagerr">同意协议</label>
        <button :disabled="!isagerr">下一步</button>
        <br>
        <h2>{{isagerr}}</h2>
        <input type="checkbox" value="测试选项1" v-model="totalcheckbox">测试选项1
        <input type="checkbox" value="测试选项2" v-model="totalcheckbox">测试选项2
        <input type="checkbox" value="测试选项3" v-model="totalcheckbox">测试选项3
        <input type="checkbox" value="测试选项4" v-model="totalcheckbox">测试选项4
        <br>
        <label v-for="item in totealselect">
            <input type="checkbox" :value="item" v-model="totalcheckbox">{{item}}
        </label>
        <br>
        <h2>{{totalcheckbox}}</h2>

        <!--下拉选择框-->
        <select v-model="selectvalue">
            <option>测试选项1</option>
            <option>测试选项2</option>
            <option>测试选项3</option>
            <option>测试选项4</option>
            <option>测试选项5</option>
        </select>
        <br>
        <h2>{{selectvalue}}</h2>

        <!--v-once为只渲染一次，不随数据的改变而改变-->
        <h1 v-once>{{message + " " + message}}</h1>

        <!--v-pre为不解析，原封不动的显示出来-->
        <h1 v-pre>{{message}}</h1>

        <!--v-for为循环，后接表达式：变量 in 列表-->
        <ul>
            <li v-for="item in textlist">{{item}}</li>
        </ul>
        <!--
            绑定key用于更高效的更新虚拟DOM渲染
            注意：key不能重复，不能用index
        -->
        <ul>
            <li v-for="item in textlist" :key="item">{{item}}</li>
        </ul>
        <!--在遍历的过程中获取索引值-->
        <ul>
            <li v-for="(item,index) in textlist">{{index+1}}:{{item}}</li>
        </ul>
        <!--获取key和value 格式：(value,key)-->
        <ul>
            <li v-for="(value,key) in info">{{key}}:{{value}}</li>
        </ul>
        <!--获取key和value 格式：(value,key)-->
        <ul>
            <li v-for="(value,key,index) in info">{{key}}:{{value}},{{index}}</li>
        </ul>

        <!--v-html为解析HTML，后接html字符串-->
        <h1 v-html="url"></h1>

        <!--v-bind用于动态绑定属性（双大括号无效）-->
        <a v-bind:href="url2">v-bind测试</a>
        <!--v-bind简写:-->
        <a :href="url2">v-bind简写测试</a>

        <!--
            动态绑定样式，后接表达式：{属性名 : 属性值}
            属性值注意增加单引号，否则会解析为变量
        -->
        <h2 :style="{fontSize: '50px',color: color}">{{message}}</h2>
        <!--数组语法（不常用）-->
        <h2 :style="[mystyle]">{{message}}</h2>

        <!--动态绑定class，后接表达式：{class名 : 布尔值}-->
        <h2 v-bind:class="{active: isactive,line12: isline}">{{message}}</h2>
        <h2 v-bind:class="getclass()">{{message}}</h2>

        <!--计算属性-->
        <h2>{{maintext}}</h2>

        <!--
            事件绑定，后接表达式：命令
            获取event事件对象：$eveut
        -->
        <button @click="btnClick()">按钮</button>
        <button v-on:click="btnClick()">按钮</button>

        <!--stop修饰符的使用（避免事件冒泡）-->
        <div @click="divClick()">
            <button @click.stop="btnClick()">stop修饰符按钮</button>
        </div>

        <!--prevent修饰符的使用-->
        <form>
            <input type="submit" value="提交" @click.prevent="btnClick()">
        </form>

        <!--once修饰符的使用：只能触发一次事件-->
        <button @click.once="btnClick()">once修饰符按钮</button>

        <br>
        <!--监听键盘的按键-->
        <input type="txt" @keyup="keyup()">
        <input type="txt" @keyup.enter="keyup()">

        <!--v-if
            用于控制显现/隐藏，true为显现，false为隐藏
            注意：此方法是完全隐藏，不显示在dom中
            适合切换频率低的环境
        -->
        <h2 v-if="true">{{message}}</h2>
        <!--v-else与v-if的值相反，当v-if为false时v-else则显示-->
        <h2 v-else>{{message}}</h2>

        <!--
            v-show用于控制显现/隐藏，true为显现，false为隐藏
            注意：只是给元素增加display:none
            适合切换频率高的环境
        -->
        <h2 v-show="true">{{message}}</h2>




    </div>
    <script src="vue.js"></script>
    <script>
        app = new Vue({
            //声明要绑定的id
            el: '#app',
            //数据对象 
            data: {
                message: '测试文本',
                textlist: ["测试列表1", "测试列表2", "测试列表3", "测试列表4"],
                info: {
                    name: "why",
                    age: 18,
                    height: 1.88
                },
                url: "<a href='http://www.baidu.com'>百度一下</a>",
                url2: "http://www.baidu.com",
                isactive: true,
                isline: false,
                color: 'red',
                mystyle: { color: 'red' },
                sex: "男",
                isagerr: false,
                totalcheckbox: [],
                selectvalue: "",
                totealselect: ["测试选项1", "测试选项2", "测试选项3", "测试选项4", "测试选项5"],
            },
            //计算属性：属性名称: function(){} （调用时不需要加小括号）
            computed: {
                maintext: function () {
                    return this.message + '     ' + this.message
                }
            },
            //定义方法：方法名称: function(){}
            //当前对象内需要加this
            methods: {
                btnClick() {
                    this.isactive = !this.isactive
                },
                getclass() {
                    return { active: this.isactive, line12: this.isline }
                },
                divclick() {
                    console.log("divclick")

                },
                btnclick() {
                    console.log("btnclick")
                },
                keyup() {
                    console.log("keyup")
                },
                listclick() {
                    //注意：数组名[下标]=XX 不会刷新
                    //unshift()    在数组最签前面增加元素（支持多个参数）
                    //push()    在数组最后增加元素（支持多个参数）
                    //pop()    删除数组最后的一个元素
                    //shift()    删除数组第一个元素
                    //splice()
                    //删除元素：splice(位置,删除几个元素)
                    //插入元素：splice(位置,0,插入的元素[,插入的元素]...)
                    //替换元素：splice(位置,替换几个元素,替换的值[,替换的值]...)
                    this.textlist.push("增加元素1", "增加元素2")

                    //filter函数的使用
                    let nums = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
                    let newnubs = nums.filter(function (n) {
                        return n < 50
                    })
                    console.log(newnubs)

                    //map函数的使用
                    let new2nums = newnubs.map(function (n) {
                        return n * 2
                    })
                    console.log(newnubs)

                    //reduce函数的使用：对数组中的所有内容进行汇总
                    new3nums.reduce(function (prevalue, n) {
                        return prevalue + n
                    })
                    console.log(new3nums)

                    //箭头函数（Lambda表达式）
                    const sum = (num1, num2) => {
                        return num1 + num2
                    }
                    //箭头函数简写
                    const sum = (num1, num2) => num1 + num2

                },
            }
        })
    </script>
</body>

</html>